# tested with python 3.2, numpy 1.6.1, scipy 0.10.1

import math
import csv;
from numpy import linspace
from scipy import exp, array
from scipy.signal import firwin, lsim
from scipy.fftpack import fft, ifft
import genblepcommon
from  sys import exit

a500_unfiltered, a1200_unfiltered = genblepcommon.prepare_unfiltered()

class BiquadFilter(object):
    
	def __init__(self, b0, b1, b2, a1, a2):

		self.b0 = b0;
		self.b1 = b1;
		self.b2 = b2;
		self.a1 = a1;
		self.a2 = a2;
		self.reset()

	def reset(self):

		self.x1 = 0.0;
		self.x2 = 0.0;
		self.y1 = 0.0;
		self.y2 = 0.0;

	def filter(self, x0):

		y0 = self.b0*x0 + self.b1*self.x1 + self.b2*self.x2 - self.a1*self.y1 - self.a2*self.y2;
		self.x2 = self.x1;
		self.x1 = x0;

		self.y2 = self.y1;
		self.y1 = y0;

		return y0;

	def make_stable(self, first_sample):

		for i in range(10000):
			self.filter(first_sample);


def z_transform(ts):

	if (len(ts[0]) != 1):
		sys.exit();
	if (ts[0][0] != 1):
		sys.exit();
	if (len(ts[1]) == 1):
		A = 0;
		B = 0;
		C = ts[1][0];
	elif (len(ts[1]) == 2):
		A = 0;
		B = ts[1][0];
		C = ts[1][1];
	elif (len(ts[1]) == 3):
		A = ts[1][0];
		B = ts[1][1];
		C = ts[1][2];
	else:
		sys.exit();

	if (C != 1):
		sys.exit();

	T = 1 / genblepcommon.AMIGA_CLOCK;
	a0 = 4*A + 2*B*T + T*T;
	b0 = T*T / a0;
	b1 = 2*T / a0;
	b2 = T*T / a0;
	a1 = (2*T*T - 8*A) / a0;
	a2 = (4*A - 2*B*T + T*T) / a0;

	return BiquadFilter(b0, b1, b2, a1, a2);

def filter_signal(signal, amiga_model, audio_filter_mode):
    
	ts1, ts2 = genblepcommon.get_amiga_filter_ts(amiga_model, audio_filter_mode)
	bq1 = z_transform(ts1)
	bq2 = z_transform(ts2)

	if (ts2 != ( [1], [1] )):
		r = filter_signal_core(bq2, signal)
	else:
		r = signal

	if (ts1 != ( [1], [1] )):
		r = filter_signal_core(bq1, r);

	return r;

def filter_signal_core(filter, signal):

    filter.reset();
    filter.make_stable(signal[0]);
    
    newsignal = [0]*len(signal);
    for i in range(len(signal)):
        newsignal[i] = filter.filter(signal[i]);
    
    return newsignal;

def calc_model_500(model):

	print(model)

	amiga500_on = filter_signal(a500_unfiltered, model, 'led filter on')
	amiga500_off = filter_signal(a500_unfiltered, model, 'led filter off')

	genblepcommon.blep_calc('bq-{0}'.format(model), 
							amiga500_off, amiga500_on, a500_unfiltered)

def calc_model_1200(model):

	print(model)

	amiga1200_on = filter_signal(a1200_unfiltered, model, 'led filter on')
	amiga1200_off = filter_signal(a1200_unfiltered, model, 'led filter off')

	genblepcommon.blep_calc('bq-{0}'.format(model), 
							amiga1200_off, amiga1200_on, a1200_unfiltered)

def main():

	models500 = ["A500 R6a7", "A500", "A500+", "A600", "A2000 #1", "A2000 #2", "A3000", "CDTV", "A500 WinUAE"]
	models1200 = ["A1200", "A1200 #2", "CD32", "A4000", "A1200 WinUAE"]

	print("")
	print(genblepcommon.VIDEO_MODE)
	print("")

	for model in models500:
		calc_model_500(model)

	for model in models1200:
		calc_model_1200(model)

if __name__ == '__main__':

	genblepcommon.AMIGA_CLOCK = 3546895
	genblepcommon.VIDEO_MODE = 'PAL'

	main()

	genblepcommon.AMIGA_CLOCK = 3579545
	genblepcommon.VIDEO_MODE = 'NTSC'

	main()

